import React, { ReactElement, Fragment } from 'react';
import {
  Input,
  Form,
  Radio,
  Checkbox,
  DatePicker,
  Select,
  Row,
  Col,
  Cascader,
  TreeSelect,
} from 'antd';
import moment from 'moment';
import { PHONE_REGULAR, PHOEN_ERR } from '@/utils/utils';
import styles from './index.less';
const { TextArea } = Input;

const { SHOW_PARENT } = TreeSelect;

type Item = {
  required: boolean;
  __handleChangeFlag?: boolean;
  requiredMsg?: string;
  valueType?: string;
  span: number;
  key: string;
  relatedKey?: string;
  submitKey?: string;
  group: string;
  type: string;
  format?: string;
  placeholder?: string;
  option: any[];
  position: string;
  value: string;
  __originData?: boject;
};
type FormProps = {
  formItemArray: Item[];
  labelAlign?: 'left' | 'right';
  form: any;
  formLayout: object;
};

const DATE_FORMAT = 'YYYY-MM-DD';
let preSpan = 0;
// INPUT_RADIO(1, "INPUT_RADIO", "单选"),
// INPUT_CHECKBOX(2, "INPUT_CHECKBOX", "多选"),
// INPUT_TEXT(3, "INPUT_TEXT", "输入"),
// INPUT_DATE(4, "INPUT_DATE", "时间"),
// SELECT(5, "SELECT", "下拉框"),
// CASCADER(6, "CASCADER", "级联选择"),

const getInput = function (item: Item, defaultPre: string, onChange?: (any) => void): ReactElement {
  let result: ReactElement = <div></div>;
  switch (item.type) {
    case 'INPUT_RADIO':
      result = (
        <Radio.Group>
          {item.option &&
            item.option.map((item) => {
              const typeItem = typeof item === 'string';
              const key = typeItem ? item : item.label;
              const value = typeItem ? item : item.value;
              return (
                <Radio key={key} value={value}>
                  {key}
                </Radio>
              );
            })}
        </Radio.Group>
      );
      break;
    case 'INPUT_CHECKBOX':
      result = (
        <Checkbox.Group>
          {item.option &&
            item.option.map((item) => {
              const typeItem = typeof item === 'string';
              const key = typeItem ? item : item.label;
              const value = typeItem ? item : item.value;
              return (
                <Checkbox key={key} value={value}>
                  {key}
                </Checkbox>
              );
            })}
        </Checkbox.Group>
      );
      break;
    case 'INPUT_TEXT':
      const { valueType } = item;
      const props = {
        type: valueType === 'PHONE' || valueType === 'NUMBER' ? 'number' : 'text',
      };
      result = <Input {...props} placeholder={item.placeholder || defaultPre} />;
      break;
    case 'INPUT_DATE':
      result = (
        <DatePicker
          style={{ width: '100%' }}
          placeholder={item.placeholder || defaultPre}
          format={item.format || DATE_FORMAT}
        />
      );
      break;
    case 'SELECT':
    case 'MULTIPLE_SELECT':
      const mode = item.type === 'SELECT' ? 'default' : 'multiple';
      const propsSelect: any = { mode, placeholder: item.placeholder || defaultPre };
      if (onChange) {
        propsSelect.onChange = onChange;
      }
      result = (
        <Select {...propsSelect}>
          {item.option &&
            item.option.map((item) => {
              const typeItem = typeof item === 'string';
              const key = typeItem ? item : item.label;
              const value = typeItem ? item : item.value;
              return (
                <Select.Option key={key} value={value}>
                  {key}
                </Select.Option>
              );
            })}
        </Select>
      );
      break;
    case 'CASCADER':
      result = <Cascader options={item.option} placeholder={item.placeholder || defaultPre} />;
      break;
    case 'TEXTAREA':
      result = <TextArea rows={4} placeholder={item.placeholder || defaultPre} />;
      break;
    case 'TREE_SELECT':
      const treeData = [];
      const options = item.option;
      if (options) {
        for (const key in options) {
          if (options.hasOwnProperty(key)) {
            const element = options[key];
            const data = {
              title: key,
              value: key,
              key,
              checkable: false,
              children: [],
            };
            data.children = element.map((item) => {
              return {
                title: item,
                value: item,
                key: item,
              };
            });
            treeData.push(data);
          }
        }
      }
      const tProps = {
        treeData,
        treeCheckable: true,
        showCheckedStrategy: SHOW_PARENT,
        searchPlaceholder: defaultPre,
        // style: {
        //   width: '100%',
        // },
      };
      result = <TreeSelect {...tProps} />;
      break;
    default:
      result = <div>{item.key}</div>;
      break;
  }
  return result;
};

const defaultLayout = {
  labelCol: {
    xs: { span: 24 },
    sm: { span: 8 },
  },
  wrapperCol: {
    xs: { span: 24 },
    sm: { span: 14 },
  },
};
class NormalForm extends React.Component<FormProps> {
  state = {
    linkItem: '',
  };
  handleSelectChange = (key1: string, key2: string, value: string) => {
    this.setState({
      [key1]: value,
    });
    this.props.form.setFieldsValue({
      [key2]: [],
    });
  };
  handleItem = (item: Item, formLayout: any, getFieldDecorator: any, onChange?: (any) => void) => {
    const { type, valueType, key, requiredMsg, required, value, submitKey } = item;
    const span = item.span === 24 ? 24 : 12;
    const defaultPre = type === 'INPUT_TEXT' ? '请输入' : '请选择';
    const rules: any[] = [{ required: required, message: requiredMsg || `${defaultPre}${key}` }];
    if (valueType === 'PHONE') {
      rules.push({
        pattern: PHONE_REGULAR,
        message: PHOEN_ERR,
      });
    }
    let formLayoutCopy;
    // 传入form布局时不用修改，默认值时需要进行适配
    if (formLayout) {
      formLayoutCopy = formLayout;
    } else {
      formLayoutCopy = JSON.parse(JSON.stringify(defaultLayout));
      // 连续两个都为12 的选项，增加offset
      if (preSpan === 12 && span === 12) {
        formLayoutCopy.labelCol.sm.offset = 2;
        preSpan = 0;
      } else {
        preSpan = span;
      }
      if (span === 24) {
        formLayoutCopy.labelCol.sm.span = Math.ceil((formLayoutCopy.labelCol.sm.span * 12) / span);
        formLayoutCopy.wrapperCol.sm.span = 24 - formLayoutCopy.labelCol.sm.span;
      }
    }
    let initialValue: any = value;
    if (type === 'INPUT_DATE') {
      initialValue = value ? moment(value) : null;
    } else if (type === 'MULTIPLE_SELECT') {
      initialValue = value || [];
    }
    const props: any = {
      rules,
    };
    if (initialValue) {
      // initialValue 赋值为null时，select 的placeholder 不能展示
      props.initialValue = initialValue;
    }
    return (
      <Col span={span}>
        <Form.Item {...formLayoutCopy} key={key} label={key}>
          {getFieldDecorator(submitKey || key, props)(getInput(item, defaultPre + key, onChange))}
        </Form.Item>
      </Col>
    );
  };
  render() {
    const { form, labelAlign = 'right', formItemArray = [], formLayout = null } = this.props;
    const { getFieldDecorator } = form;
    preSpan = 0;
    let relatedKey = '';
    let relatedParentKey = '';
    // 表单联动特殊处理
    const formItemResult = formItemArray.map((item: Item) => {
      if (item.relatedKey) {
        relatedParentKey = item.key;
        relatedKey = item.relatedKey || '';
        // item.option = (item.option && Object.keys(item.option)) || [];
        item.__handleChangeFlag = true;
      } else if (item.key === relatedKey) {
        item.__originData = item.__originData || item.option;
        const option2Key = this.state[relatedParentKey];
        item.option = option2Key ? item.__originData[option2Key] : [];
        item.type = 'MULTIPLE_SELECT';
      }
      return item;
    });
    return (
      <Form className={styles['form-container']} labelAlign={labelAlign}>
        <Row>
          {formItemResult.map((item: Item) => {
            // 表单联动特殊处理
            // if (item.type === 'MULTICLE_CASCADER') {
            //   const keys = item.key.split(',');
            //   const option1 = (item.option && Object.keys(item.option)) || [];
            //   const option2Key = this.state[keys[0]];
            //   const item1 = {
            //     ...item,
            //     key: keys[0],
            //     option: option1,
            //     type: 'SELECT',
            //   };
            //   const item2 = {
            //     ...item,
            //     key: keys[1],
            //     option: option2Key ? item.option[option2Key] : [],
            //     type: 'MULTIPLE_SELECT',
            //   };
            //   return (
            //     <Fragment>
            //       {this.handleItem(
            //         item1,
            //         formLayout,
            //         getFieldDecorator,
            //         this.handleSelectChange.bind(this, item1.key, item2.key),
            //       )}
            //       {this.handleItem(item2, formLayout, getFieldDecorator)}
            //     </Fragment>
            //   );
            // }
            if (item.__handleChangeFlag) {
              return this.handleItem(
                item,
                formLayout,
                getFieldDecorator,
                this.handleSelectChange.bind(this, item.key, item.relatedKey),
              );
            }
            return this.handleItem(item, formLayout, getFieldDecorator);
          })}
        </Row>
      </Form>
    );
  }
}

export default NormalForm;
